﻿using UnityEngine;

[ExecuteInEditMode]
[RequireComponent(typeof(SpriteRenderer))]
public class SpriteAdapter : MonoBehaviour
{
    public enum EFill
    {
        None,
        FullScreen,
        Flush4Side,
        ShowAll,
        ByWidth,
        ByHeight,
        WidthOnly,
        HeightOnly
    }

    public enum EHorAlign
    {
        Center,
        Left,
        Right
    }

    public Camera _camera;
    public EFill fill = EFill.None;
    public EHorAlign horAlign = EHorAlign.Center;

    private float screenRatio;
    private SpriteRenderer spriteRenderer;
    private Sprite sprite;
    private float left, right;
    private EHorAlign currAlign;
    private Vector3 currPos;
    private bool hasAdaptSize;

    void Start()
    {
        if (!_camera) _camera = Camera.main;
        if (!_camera.orthographic)
        {
            Debug.LogError($"{name} 上的 SpriteAdapter 组件仅对正交相机有效！");
            return;
        }
        UpdateRelativePos();
    }

    private void Update()
    {
        if (currAlign != horAlign)
        {
            currAlign = horAlign;
            UpdateRelativePos();
        }
        if (currPos != transform.position)
        {
            currPos = transform.position;
            UpdateRelativePos();
        }
    }

    private void UpdateRelativePos()
    {
        Vector2 screenSize = new Vector2(_camera.orthographicSize * 2 * _camera.aspect, _camera.orthographicSize * 2);
        left = transform.position.x + screenSize.x * 0.5f;
        right = screenSize.x * 0.5f - transform.position.x;
    }


    private void LateUpdate()
    {
        _camera ??= Camera.main;
        if (!_camera.orthographic)
        {
            return;
        }

        hasAdaptSize = false;

#if UNITY_EDITOR
        if (!Application.isPlaying)
        {
            AdaptSize();
            hasAdaptSize = true;
        }
#endif

        spriteRenderer ??= GetComponent<SpriteRenderer>();
        if (sprite != spriteRenderer.sprite)
        {
            sprite = spriteRenderer.sprite;
            if (!hasAdaptSize)
            {
                AdaptSize();
                hasAdaptSize = true;
            }
        }

        if (screenRatio != _camera.aspect)
        {
            screenRatio = _camera.aspect;
            if (!hasAdaptSize)
            {
                AdaptSize();
                hasAdaptSize = true;
            }
            AdaptPos();
        }
    }

    private void AdaptPos()
    {
        Vector2 screenSize = new Vector2(_camera.orthographicSize * 2 * _camera.aspect, _camera.orthographicSize * 2);
        Vector3 pos = transform.position;
        switch (horAlign)
        {
            case EHorAlign.Left:
                pos.x = -screenSize.x * 0.5f + left;
                break;
            case EHorAlign.Right:
                pos.x = screenSize.x * 0.5f - right;
                break;
        }
        transform.position = pos;
    }

    private void AdaptSize()
    {
        if (!sprite)
        {
            return;
        }

        Vector3 scale = transform.localScale;
        scale.z = 1;
        Vector2 screenSize = new Vector2(_camera.orthographicSize * 2 * _camera.aspect, _camera.orthographicSize * 2);
        spriteRenderer ??= GetComponent<SpriteRenderer>();
        switch (fill)
        {
            case EFill.FullScreen:
                //填满整个屏幕
                if (sprite.texture.width / (float)sprite.texture.height > screenSize.x / screenSize.y)
                {
                    scale.y *= screenSize.y / spriteRenderer.bounds.size.y;
                    scale.x = scale.y;
                }
                else
                {
                    scale.x *= screenSize.x / spriteRenderer.bounds.size.x;
                    scale.y = scale.x;
                }
                break;
            case EFill.Flush4Side:
                //4边贴紧全屏
                scale.x *= screenSize.x / spriteRenderer.bounds.size.x;
                scale.y *= screenSize.y / spriteRenderer.bounds.size.y;
                break;
            case EFill.ShowAll:
                //在屏幕上显示图片的全部内容
                if (sprite.texture.width / (float)sprite.texture.height < screenSize.x / screenSize.y)
                {
                    scale.y *= screenSize.y / spriteRenderer.bounds.size.y;
                    scale.x = scale.y;
                }
                else
                {
                    scale.x *= screenSize.x / spriteRenderer.bounds.size.x;
                    scale.y = scale.x;
                }
                break;
            case EFill.ByHeight:
                //根据图片高度进行填充
                scale.y *= screenSize.y / spriteRenderer.bounds.size.y;
                scale.x = scale.y;
                break;
            case EFill.ByWidth:
                //根据图片宽度进行填充
                scale.x *= screenSize.x / spriteRenderer.bounds.size.x;
                scale.y = scale.x;
                break;
            case EFill.WidthOnly:
                //只要宽度全部显示
                scale.x *= screenSize.x / spriteRenderer.bounds.size.x;
                break;
            case EFill.HeightOnly:
                //只要高度全部显示
                scale.y *= screenSize.y / spriteRenderer.bounds.size.y;
                break;
        }
        transform.localScale = scale;
    }
}